package org.javaee05.component;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.javaee05.conf.SysConstants;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/*使用druid管理连接池*/
public class jdbcConnectionPool {
    /*构造方法私有化,该类成员全是静态成员*/
    private jdbcConnectionPool() {
    }

    /*声明connectionThreadLocal线程变量,*/
    private static ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<Connection>();
    /*声明druiddatasource全局变量,用来保存指向连接池对象的引用,所有方法都可以访问这个引用*/
    public static DruidDataSource druidDataSource = null;

    static {
        /*当前类被加载时执行的静态代码块*/

        Properties prop = loadPropertiesFile(SysConstants.JDBC_CONF_FILE);
        try {
            /*用配置文件对象作为参数创建数据库连接池,用dataSource引用保存连接池对象*/
            /*把dataSource声明为全局静态变量,否则其他方法无法访问这个连接池*/
            druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(prop);
            druidDataSource.init();//显示调用init（）方法初始化连接池
            // 第一次调用获取连接的方法也会初始化连接池 druidDataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static Properties loadPropertiesFile(String filePath) {
        if (null == filePath || filePath.equals("")) {
            throw new IllegalArgumentException(
                    "Properties file path can not be null" + filePath);
        }
        Properties prop = new Properties();
        try {
            /*根据配置文件路径加载配置文件,返回一个Properties对象*/
            prop.load(jdbcConnectionPool.class.getClassLoader().getResourceAsStream(filePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return prop;
    }

    /*暴露一个静态方法给外部*/
    public static Connection getConnection() {
            Connection connection = connectionThreadLocal.get();
        try {
            if(null == connection){
                //从连接池中取一个connection,连接池会返回一个空闲的connection
                connection = druidDataSource.getConnection(); //从连接池中取一个connection
                connectionThreadLocal.set(connection);   //放入线程变量中
            }
        } catch (SQLException e) {
           e.printStackTrace();
        }
        return connection;
    }
    /*暴露一个静态方法用来关闭当前线程中的connection对象*/
    /*如果连接对象不关闭的话,当100个连接对象都被使用后,连接池将会没有新的连接对象,连接将会处于永久等待状态*/
    public static void closeConnection()
    {
        /*从线程变量中取出connection*/
        Connection connection = connectionThreadLocal.get();
        if(null != connection){
            try {
                connection.close();
                connectionThreadLocal.remove();
            } catch (SQLException e) {
                 e.printStackTrace();
            }
        }
    }
    public static void startTransaction()
    {
        Connection conn = connectionThreadLocal.get();
        try{
            if(conn==null){
                conn=getConnection();
                connectionThreadLocal.set(conn);
            }
            conn.setAutoCommit(false);
        }catch(Exception e){
             e.printStackTrace();
        }
    }
    public static void commit(){
        try{
            Connection conn=connectionThreadLocal.get();
            if(null!=conn){
                conn.commit();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void rollback(){
        try{
            Connection conn=connectionThreadLocal.get();
            if(conn!=null){
                conn.rollback();
                connectionThreadLocal.remove();
            }
        }catch(Exception e){
             e.printStackTrace();
        }
    }
}
